﻿using iTool.Cloud.Center.Model;

using Newtonsoft.Json;

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;

namespace iTool.Cloud.Center.ServiceProvider.StorageProvider
{
    internal class iStorageReminderMaster
    {

        #region static
        [JsonIgnore]
        static object _LockClusterReminders;
        [JsonIgnore]
        static ConcurrentDictionary<string, iStorageReminderMaster> ClusterReminders { get; set; }

        static iStorageReminderMaster()
        {
            _LockClusterReminders = new object();
            ClusterReminders = new ConcurrentDictionary<string, iStorageReminderMaster>();
        }

        internal static iStorageReminderMaster GetStorageMasterProvide(string cluster)
        {
            if (ClusterReminders.TryGetValue(cluster, out iStorageReminderMaster iStorage))
            {
                return iStorage;
            }

            lock (_LockClusterReminders)
            {
                if (ClusterReminders.TryGetValue(cluster, out iStorage))
                {
                    return iStorage;
                }
                else
                {
                    var keyValue = StorageProvider.iStorage.GetKeyValue(cluster, "Reminder");

                    iStorage = new iStorageReminderMaster();

                    if (!string.IsNullOrEmpty(keyValue.Value))
                    {
                        iStorage = JsonConvert.DeserializeObject<iStorageReminderMaster>(keyValue.Value);
                    }

                    iStorage.Cluster = cluster;
                    iStorage.Reminders = iStorage.Reminders ?? new ConcurrentDictionary<string, List<ReminderOptions>>();
                    return iStorage;
                }
            }
        }
        #endregion



        [JsonIgnore]
        internal Subject<bool> _subject;
        [JsonIgnore]
        public string Cluster { get; set; }

        public ConcurrentDictionary<string, List<ReminderOptions>> Reminders { get; set; }

        internal void StartSubjecter()
        {
            if (_subject == null)
            {
                // 计划任务
                _subject = new Subject<bool>();
                _subject.Buffer(TimeSpan.FromSeconds(10), 30) // 1分钟 或者 30 条
                    .Where(x => x.Count > 0)
                    .Select(list => Observable.FromAsync(() => iStorage.BatchWriteAsync(Cluster, "Reminder", this)))
                    .Concat()
                    .Subscribe();
            }
        }

        internal void Upsert()
        {
            _subject.OnNext(true);
        }

    }

}
